package com.qiantu.api.db;

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.hjq.http.lifecycle.ApplicationLifecycle;
import com.hjq.http.listener.HttpCallback;
import com.hjq.http.listener.OnHttpListener;
import com.qiantu.api.entity.ControllerBean;
import com.qiantu.api.entity.DeviceBean;
import com.qiantu.api.entity.DeviceBindGroupBean;
import com.qiantu.api.entity.DeviceCustomKeyBean;
import com.qiantu.api.entity.FloorBean;
import com.qiantu.api.entity.HouseBean;
import com.qiantu.api.entity.RoomBean;
import com.qiantu.api.entity.SceneBean;
import com.qiantu.api.entity.SourceHomepageBean;
import com.qiantu.api.entity.UniversalDeviceAction;
import com.qiantu.api.entity.UniversalDeviceData;
import com.qiantu.api.http.LLHttpManager;
import com.qiantu.api.http.model.HttpData;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;

public class HouseDataManager implements OnHttpListener {

    private static final int DATACONUT = 10;
    private Context context;
    private OnListener mOnListener;
    private int apiSuccessCount;
    private int apiEndCount = -1;
    public boolean isCanceled;
    private int saveDBCount;

    private List<HouseBean> remoteHouseBeans;
    private List<FloorBean> remoteFloorBeans;
    private List<RoomBean> remoteRoomBeans;
    private List<SceneBean> remoteSceneBeans;
    private List<DeviceBean> remoteDeviceBeans;
    private List<DeviceBean> remoteDeviceGroupBeans;
    private List<ControllerBean> remoteControllerBeans;
    private List<DeviceBindGroupBean> remoteDeviceBindGroupBeans;
    private List<SourceHomepageBean> remoteSourceHomepageBeans;
    private List<DeviceCustomKeyBean> remoteDeviceCustomKeyBeans;
    private List<UniversalDeviceData> remoteDeviceActionBeans;
    private Handler mHandler;
    private String currentHouseSerialNo;
    private boolean isChangeAccount = false;
    private Map<String, Object> changeAccountData;
    List<String> errorMessages = new ArrayList<>();

    public HouseDataManager(Context context) {
        this.context = context;
        mHandler = new Handler();
    }

    public void setChangeAccountData(String phoneSerialNo, String token){
        isChangeAccount = true;
        changeAccountData = new HashMap<>();
        changeAccountData.put("platform", 2);
        changeAccountData.put("phoneName", Build.MANUFACTURER + "_" + Build.MODEL);
        changeAccountData.put("phoneSerialNo", phoneSerialNo);
        changeAccountData.put("token", token);
        changeAccountData.put("version", Build.VERSION.RELEASE);
    }

    public void initHouseData(String houseSerialNo, boolean isDelete, OnListener listener) {
        //还正在获取房屋数据
        if(apiEndCount != -1){
            return;
        }
        this.mOnListener = listener;
        if (mOnListener != null) {
            mOnListener.onStart();
        }
        apiEndCount = 0;
        apiSuccessCount = 0;
        saveDBCount = 0;
        remoteHouseBeans = null;
        remoteFloorBeans = null;
        remoteRoomBeans = null;
        remoteSceneBeans = null;
        remoteDeviceBeans = null;
        remoteDeviceGroupBeans = null;
        remoteControllerBeans = null;
        remoteSourceHomepageBeans = null;
        remoteDeviceCustomKeyBeans = null;
        currentHouseSerialNo = houseSerialNo;
        LLHttpManager.getbasichouseinfolist(new ApplicationLifecycle(), new HttpCallback<HttpData<List<HouseBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<HouseBean>> result) {
                super.onSucceed(result);
                //空房屋也返回成功
                if (result == null || result.getData() == null || result.getData().size() == 0) {
                    if (mOnListener != null) {
                        LLHouseDBManager.getInstance(context).clearFromDB();
                        LLFloorDBManager.getInstance(context).clearFromDB();
                        LLRoomDBManager.getInstance(context).clearFromDB();
                        LLDeviceDBManager.getInstance(context).clearFromDB();
                        LLSceneDBManager.getInstance(context).clearFromDB();
                        LLControllerDBManager.getInstance(context).clearFromDB();
                        LLDeviceGroupDBManager.getInstance(context).clearFromDB();
                        LLSourceHomepageDBManager.getInstance(context).clearFromDB();
                        LLDeviceCustomDBManager.getInstance(context).clearFromDB();
                        LLDeviceActionDBManager.getInstance(context).clearFromDB();
                        mOnListener.onSuccess(null);
                        mOnListener.onEnd();
                        apiEndCount = -1;
                    }
                    Log.i("lzxzx", "house is empty" + "---apiSuccessCount:" + apiSuccessCount);
                    return;
                }
                apiSuccessCount++;
                apiEndCount++;
                remoteHouseBeans = result.getData();
                //当删除房屋或者退出房屋，就直接去第一个房屋为默认房屋
                if (TextUtils.isEmpty(currentHouseSerialNo) || isDelete) {
                    currentHouseSerialNo = remoteHouseBeans.get(0).getHouseSerialNo();
                }
                initFloorData(currentHouseSerialNo);
                initRoomData(currentHouseSerialNo);
                initDeviceData(currentHouseSerialNo);
                initDeviceGroupData(currentHouseSerialNo);
                initSceneData(currentHouseSerialNo);
                initControllerData(currentHouseSerialNo);
                initSourceHomepage(currentHouseSerialNo);
                initDeviceCustomList(currentHouseSerialNo);
                initDeviceTgpactionsList(currentHouseSerialNo);
            }

            @Override
            public void onFail(Exception e) {
                super.onFail(e);
                if (mOnListener != null) {
                    errorMessages.add(e.getMessage());
                    mOnListener.onFailed(errorMessages);
                    mOnListener.onEnd();
                }
                apiEndCount = -1;
            }

            @Override
            public void onEnd(Call call) {
            }
        });
    }

    public void cancel(){
        isCanceled = true;
        apiEndCount = -1;
    }

    private void checkApiComplete() {
        apiEndCount++;
        if(apiEndCount == DATACONUT && !isCanceled){
            if (apiSuccessCount != DATACONUT) {
                String error = "";
                for(String s : errorMessages){
                    error += s + ";";
                }
                Log.i("lzxzx", "onFail:" + error);
                if (mOnListener != null) {
                    mOnListener.onFailed(errorMessages);
                    mOnListener.onEnd();
                }
                apiEndCount = -1;
            } else {
                if (isChangeAccount){
                    changeServiceAccount();
                }else {
                    onApiComplete();
                }
            }
        }
    }

    /**
     * 切换服务器账号
     */
    private void changeServiceAccount() {
        LLHttpManager.changeServerAccount(new ApplicationLifecycle(), changeAccountData, new HttpCallback<HttpData<Void>>(null){
            @Override
            public void onSucceed(HttpData<Void> result) {
                onApiComplete();
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
                if (mOnListener != null) {
                    mOnListener.onFailed(errorMessages);
                    mOnListener.onEnd();
                    apiEndCount = -1;
                }
            }
        });
    }

    private void onApiComplete(){
        new Thread() {
            @Override
            public void run() {
                remoteDeviceBeans.addAll(remoteDeviceGroupBeans);
                LLHouseDBManager.getInstance(context).refreshAllHousesTx(remoteHouseBeans, null);
                LLFloorDBManager.getInstance(context).refreshAllFloorsTx(remoteFloorBeans, null);
                LLRoomDBManager.getInstance(context).refreshAllRoomsTx(remoteRoomBeans, null);
                LLDeviceDBManager.getInstance(context).refreshAllDevicesTx(remoteDeviceBeans, null);
                LLDeviceGroupDBManager.getInstance(context).refreshAllDevicesTx(remoteDeviceBindGroupBeans,null);
                LLSceneDBManager.getInstance(context).refreshAllScenesTx(remoteSceneBeans, null);
                LLControllerDBManager.getInstance(context).refreshAllControllersTx(remoteControllerBeans);
                LLSourceHomepageDBManager.getInstance(context).refreshAllSoucecesTx(remoteSourceHomepageBeans,null);
                LLDeviceCustomDBManager.getInstance(context).refreshAllCustomsTx(remoteDeviceCustomKeyBeans,null);
                LLDeviceActionDBManager.getInstance(context).refreshAllSoucecesTx(remoteDeviceActionBeans,null);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mOnListener != null) {
                            mOnListener.onSuccess(LLHouseDBManager.getInstance(context).get(currentHouseSerialNo));
                            mOnListener.onEnd();
                            apiEndCount = -1;
                        }
                    }
                });

            }
        }.start();
    }

    private void initFloorData(String houseSerialNo) {
        LLHttpManager.house_getfloors(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<FloorBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<FloorBean>> result) {
                super.onSucceed(result);
                remoteFloorBeans = result.getData();
                for(int i = 0 ;i < remoteFloorBeans.size();i++){
                    FloorBean floorBean = remoteFloorBeans.get(i);
                    if(floorBean.getType() == 1){
                        remoteFloorBeans.get(i).setFloorName("全屋");
                        break;
                    }
                }
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initRoomData(String houseSerialNo) {
        LLHttpManager.house_getrooms(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<RoomBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<RoomBean>> result) {
                super.onSucceed(result);
                remoteRoomBeans = result.getData();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initDeviceData(String houseSerialNo) {
        LLHttpManager.house_getdevices(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<DeviceBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<DeviceBean>> result) {
                super.onSucceed(result);
                remoteDeviceBeans = result.getData();
                for (int i = 0;i < remoteDeviceBeans.size();i++){
                    remoteDeviceBeans.get(i).setDeviceGroup(0);
                }
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initDeviceGroupData(String houseSerialNo) {
        LLHttpManager.house_getGroupDevice(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<DeviceBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<DeviceBean>> result) {
                super.onSucceed(result);
                remoteDeviceGroupBeans = result.getData();
                for (int i = 0;i < remoteDeviceGroupBeans.size();i++){
                    remoteDeviceGroupBeans.get(i).setDeviceSerialNo(remoteDeviceGroupBeans.get(i).getDeviceGroupSerialNo());
                    remoteDeviceGroupBeans.get(i).setDeviceGroup(1);
                    if(remoteDeviceBindGroupBeans == null){
                        remoteDeviceBindGroupBeans = remoteDeviceGroupBeans.get(i).getDeviceBindGroups();
                    }else{
                        remoteDeviceBindGroupBeans.addAll(remoteDeviceGroupBeans.get(i).getDeviceBindGroups());
                    }
                }
                apiSuccessCount++;
            }
            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }


    private void initSceneData(String houseSerialNo) {
        LLHttpManager.house_getscenes(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<SceneBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<SceneBean>> result) {
                super.onSucceed(result);
                remoteSceneBeans = result.getData();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initControllerData(String houseSerialNo) {
        LLHttpManager.getControllers(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<ControllerBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<ControllerBean>> result) {
                super.onSucceed(result);
                remoteControllerBeans = result.getData();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initSourceHomepage(String houseSerialNo) {
        LLHttpManager.getSourceHomepage(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<SourceHomepageBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<SourceHomepageBean>> result) {
                super.onSucceed(result);
                remoteSourceHomepageBeans = result.getData();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initDeviceCustomList(String houseSerialNo) {
        LLHttpManager.getCustomKeyList(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<DeviceCustomKeyBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<DeviceCustomKeyBean>> result) {
                super.onSucceed(result);
                remoteDeviceCustomKeyBeans = result.getData();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    private void initDeviceTgpactionsList(String houseSerialNo) {
        LLHttpManager.getAllDeviceTgpactions(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<UniversalDeviceAction>>(this) {
            @Override
            public void onSucceed(HttpData<UniversalDeviceAction> result) {
                super.onSucceed(result);
                remoteDeviceActionBeans = result.getData().getTgpActions();
                apiSuccessCount++;
            }

            @Override
            public void onFail(Exception e) {
                errorMessages.add(e.getMessage());
            }
        });
    }

    @Override
    public void onSucceed(Object result) {
        if (result instanceof HttpData) {
            Log.i("DataManager", "onSucceed:" + ((HttpData<?>) result).getMessage());
        }
    }

    @Override
    public void onFail(Exception e) {
        Log.i("DataManager", "onFail:" + e.getMessage());
    }

    @Override
    public void onEnd(Call call) {
        checkApiComplete();
    }

    public interface OnListener {
        default void onStart() {
        }

        default void onSuccess(HouseBean defaultHouse) {
        }

        default void onFailed(List<String> errorMessages) {
        }

        default void onEnd() {
        }
    }
}
